我覺得一個App的精髓之一就在於能夠提供什麼內容,目前看到市面上的大部分App都是會串接API作為使用,能夠提供更多更方便的功能
那麼這次不要再餵假資料了,來餵點真的
之前題目有提到是會類似IMDB的模式,那麼就串接IMDB的API吧!
我使用的是Rapid API,記得先去註冊一組自己的帳號
然後我使用的是這個IMDb的API提供
如上圖所示,被我用黃色色塊遮住的地方就是關於你的APIKey,用來作為跟這隻API溝通的Key
右邊的Code Snippets其實也有Swift的可以看Code怎麼寫的
我這邊也提供一下我的寫法
MVVM中 Model的部分負責串接API下來的資料
先觀察API的資料結構
struct HomeCellViewModel: Codable {
let d: [LayerTwo]?
}
struct LayerTwo: Codable {
let img: ImageURL?
let id: String
let movieName: String
let type: String?
let rank: Int?
let actress: String
let startYear: Int?
let period: String?
enum CodingKeys: String, CodingKey {
case img = "i"
case id
case movieName = "l"
case type = "q"
case rank
case actress = "s"
case startYear = "y"
case period = "yr"
}
}
struct ImageURL: Codable {
let imageURL: String
enum CodingKeys: String, CodingKey {
case imageURL = "imageUrl"
}
}
因為有些資料不是API一定會給,所以要使用optional的方式
// 在ViewModel內
// param就是輸入自己想要查詢的內容
func downloadData(param: String) {
var urlString = "https://imdb8.p.rapidapi.com/auto-complete"
// 一定要有這個Headers才能跟API溝通到
let headers = [
"X-RapidAPI-Key": "....(你自己的Key)",
"X-RapidAPI-Host": "imdb8.p.rapidapi.com"
]
urlString += "?q=\(param)"
let url = URL(string: urlString)!
var urlRequest = URLRequest(url: url)!
urlRequest.httpMethod = "GET"
urlRequest.allHttpHeaderFields = headers
URLSession.shared.dataTask(with: urlRequest) { data, response, error in
do {
if let data = data {
let decoder = JSONDecoder()
let result = try decoder.decode(HomeCellModel.self, from: data)
self.dataList = result
// 在outputs中定義的,會在VC綁定
// 其實就是在VC中執行tableView.reloadData()
self.reloadList?()
}
// 下面這麼一大串是為了幫助找出錯誤,因為常常在Decode的時候並不知道是哪邊錯誤
// 透過這樣Print出來就可以抓出明顯錯誤
} catch let DecodingError.dataCorrupted(context) {
print(context)
} catch let DecodingError.keyNotFound(key, context) {
print("Key '\(key)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.valueNotFound(value, context) {
print("Value '\(value)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.typeMismatch(type, context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch {
print("error: ", error)
}
}
}
如此一來,再把剛剛從VM中拿到的資料一回去Reload其實就能得到API所回傳的資料
再透過前天說的Kingfisher的串接方式,就可以把圖片顯示出來
坑:
最坑的莫非就是Decode Error,每次遇到Decode Error如果沒有上面的func,那麼就找出問題到底在哪邊
還有就是要注意哪些API所給的資料是沒有的,否則Decode Error就會找上門。